<?php

namespace app\components;

use Yii;

class PerformanceLog
{	
	const LEVEL_INFO = 'info';
	
	const LEVEL_WARNING = 'warning';
	
	const LEVEL_DANGER = 'danger';
	
	private static $instance;
	
	private $begin_time;
	
	private $end_time;
	
	private $log_time = [];
	
	public static $filePath = "/runtime/logs/";
	
	private function __construct(){}
	
	private function __clone(){}
	
    public static function getInstance()
    {
        if (!self::$instance instanceof PerformanceLog) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    // 开始记录
    public static function begin()
    {
    	$log = self::getInstance();
    	$log->begin_time = microtime(true);
    }
    
    // 中途记录
    public static function log()
    {
    	$log = self::getInstance();
    	$log->log_time[] = microtime(true);
    }
    
    // 结束记录
    public static function end()
    {
    	$log = self::getInstance();
    	$log->end_time = microtime(true);
    	$log->save();
    	$log->refresh();
    }
    
    // 保存
    private function save()
    {
    	$log = self::getInstance();
    	
    	$contents = '';
    	$day = '[' . date('Y-m-d H:i:s') . ']';
    	$cost = round($log->end_time - $log->begin_time, 3);
    	
    	if (!empty($log->begin_time)) {
    		$contents .= $day . ' ' . '[Begin At:' . $log->begin_time . ']' . PHP_EOL;
    		// 展示中间过程
    		if (count($log->log_time) > 0) {
    			foreach ($log->log_time as $k => $v) {
    				$contents .= $day . ' ' . '[When:' . $k . ']' . ' ' . '[At:' . $v . ']' . PHP_EOL;
    			}
    		}
    		$contents .= $day . ' ' . '[End At:' . $log->end_time . ']' . PHP_EOL;
    		$contents .= $day . ' ' . '[Total Cost:' . $cost . 's]' . PHP_EOL . PHP_EOL;
    		
    		if ($cost <= 1) {
    			$log->write(self::LEVEL_INFO, $contents);
    		} elseif (1 < $cost && $cost <= 2) {
    			$log->write(self::LEVEL_WARNING, $contents);
    		} elseif ($cost > 2) {
    			$log->write(self::LEVEL_DANGER, $contents);
    		}
    	}
    }

    // 写入文件
    private function write($level, $contents)
    {
    	$filename = date('md') . '_pf_' . $level . '.log';
    	
    	file_put_contents(Yii::getAlias('@app') . self::$filePath . $filename, $contents, FILE_APPEND | LOCK_EX);
    }
    
    // 清空时间
    private function refresh()
    {
    	$log = self::getInstance();
    	unset($log->begin_time);
    	unset($log->end_time);
    	$log->log_time = [];
    }
}